package gofunc

import (
	"archive/tar"
	"archive/zip"
	"compress/gzip"
	"crypto/md5"
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"io"
	"io/fs"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	//"log"
)

type FileFunc struct {
}

// 列出pathurl目录下的非目录的所有文件
func (self *FileFunc) LsNotDir(path string) []string {
	var strRet []string
	files, _ := ioutil.ReadDir(path)
	for _, f := range files {
		if !f.IsDir() {
			strRet = append(strRet, f.Name())
		}
	}
	return strRet
}

func (self *FileFunc) CopyFile(src, des string) (w int64, err error) {
	srcFile, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer srcFile.Close()

	desFile, err := os.Create(des)
	if err != nil {
		return 0, err
	}
	defer desFile.Close()

	return io.Copy(desFile, srcFile)
}

// 看是否存在目录不存在就创建一个
func (self *FileFunc) ExistDirIfNotCreat(dir string) {
	//_, err := os.Stat("./db")
	_, err := os.Stat(dir)
	if err == nil { //存在目录
		return
	} else { //不存在目录
		os.MkdirAll(dir, 0755)
	}
}

// 获取dir文件的整体大小,单位为字节，6000就是6k
func (self *FileFunc) DirSize(path string) (int64, error) {
	var size int64
	err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
		if !info.IsDir() {
			size += info.Size()
		}
		return err
	})
	return size, err
}

// 获取某文件的md5值
func (self *FileFunc) Md5(path string) (_md5 string, err error) {
	file, err := os.Open(path)
	if err != nil {
		_md5 = ""
		return "", err
	}
	defer file.Close()
	md5h := md5.New()
	io.Copy(md5h, file)
	md5str := fmt.Sprintf("%x", md5h.Sum([]byte(""))) //md5
	_md5 = md5str
	return
}

// 解压 tar.gz
// 参考 https://www.cnblogs.com/xiaofengshuyu/p/5646494.html
func (self *FileFunc) GzDeCompress(tarFile, dest string) error {
	srcFile, err := os.Open(tarFile)
	if err != nil {
		return err
	}
	defer srcFile.Close()
	gr, err := gzip.NewReader(srcFile)
	if err != nil {
		return err
	}
	defer gr.Close()
	tr := tar.NewReader(gr)
	for {
		hdr, err := tr.Next()
		if err != nil {
			if err == io.EOF {
				break
			} else {
				return err
			}
		}
		filename := dest + hdr.Name
		//log.Println(dest,hdr.Name)
		file, err := createFile(filename)
		if err != nil {
			return err
		}
		io.Copy(file, tr)
	}
	return nil
}

func createFile(name string) (*os.File, error) {
	err := os.MkdirAll(string([]rune(name)[0:strings.LastIndex(name, "/")]), 0755)
	if err != nil {
		return nil, err
	}
	return os.Create(name)
}

// ZipDir dir: 需要打包的本地文件夹路径
// dst: 保存压缩包的本地路径
// 将生成的目录打包为zip文件
//
//	zipfile := fmt.Sprintf("%s/%s_%s.zip", pathbase, houseName, lineName)
//	err3 := util.ZipDir(savepath, zipfile)
func (self *FileFunc) ZipDir(dir string, dst string) error {
	zipFile, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, 0660)
	if err != nil {
		return err
	}
	defer zipFile.Close()
	archive := zip.NewWriter(zipFile)
	defer archive.Close()
	return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
		if path == dir {
			return nil
		}
		info, _ := d.Info()
		h, _ := zip.FileInfoHeader(info)
		// 如果dir包含'a' 则去掉
		_dir := dir
		if strings.Contains(dir, "./") {
			_dir = strings.Replace(dir, "./", "", 1)
		}
		h.Name = strings.TrimPrefix(path, _dir+"/")
		if info.IsDir() {
			h.Name += "/"
		} else {
			h.Method = zip.Deflate
		}
		writer, _ := archive.CreateHeader(h)
		if !info.IsDir() {
			srcFile, _ := os.Open(path)
			defer srcFile.Close()
			io.Copy(writer, srcFile)
		}
		return nil
	})
}

// 将一堆指定的图片合并为一个pdf
//
//	//合并图片为pdf
func MergerPdf(imagePaths []string, outputPath string) error {
	//imagePaths := []string{
	//	"path/to/image1.jpg",
	//	"path/to/image2.jpg",
	//	"path/to/image3.jpg",
	//	// 添加其他图片路径...
	//}

	pdf := gofpdf.New("P", "mm", "A4", "")
	for _, imagePath := range imagePaths {
		pdf.AddPage()
		pdf.Image(imagePath, 0, 0, 210, 297, false, "", 0, "")
	}

	err := pdf.OutputFileAndClose(outputPath)
	if err != nil {
		return err
	}

	return nil
}
